﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GoodTrader.GTDownload
{
    public class CpFutureMstDownloader : CpDownLoader
    {
        private double[] arrVal = new double[GTGlobal.MaxDownloadCount];

        private DSCBO1Lib.FutureMstClass m_FutureMstFetcher = new DSCBO1Lib.FutureMstClass();
        public CpFutureMstDownloader(CpDownLoadManager aDownManager)
            : base(aDownManager)
        {
            m_FutureMstFetcher.Received += new DSCBO1Lib._IDibEvents_ReceivedEventHandler(OnReceived);
        }

        public CpFutureMstDownloader(CpDownLoadManager aDownManager, CpFutureMstData aData)
            : base(aDownManager)
        {
            mData = aData;
            m_FutureMstFetcher.Received += new DSCBO1Lib._IDibEvents_ReceivedEventHandler(OnReceived);
        }

        private CpFutureMstData mData = null;
        public CpFutureMstData Data
        {
            get { return mData; }
            set { mData = value; }
        }

        private double mEndTime = 0.0;
        public double EndTime
        {
            get { return mEndTime; }
            set { mEndTime = value; }
        }
        

        private double mOldTime = 0.0;
        // 다운로드 함수로 상속 클래스의 함수를 재정의 한다.
        public override void Download()
        {
            // 이미 다운 받은 상태이므로 먼저 베이스 클래스의 함수를 실행한다.
            base.Download();
            // 여기서 다운로드 할 내용을 실행한다.
            //System.Windows.Forms.MessageBox.Show("FutOptDownStarted");

            object code = m_CpFutureCode.GetData(0, 0);
            m_FutureMstFetcher.SetInputValue(0, code);
            try
            {
                // 데이터 수신 요청을 한다.
                m_FutureMstFetcher.Request();
            }
            catch (System.Exception ex)
            {
                Console.WriteLine(ex.ToString());
            }
        }

        public override void OnReceived()
        {
            // 베이스 클래스의 함수를 먼저 호출한다. 여기서 이벤트가 다시 설정된다. 
            base.OnReceived();

            if (mData == null)
                return;

            mEndTime = Convert.ToDouble(m_FutureMstFetcher.GetHeaderValue(82)); // 시각
            if (GTGlobal.mEndDate == 0.0 || mEndTime == 0.0)
                return;
            double curTime = Convert.ToDouble(m_FutureMstFetcher.GetHeaderValue(82)); // 시각
            double curOpen = Convert.ToDouble(m_FutureMstFetcher.GetHeaderValue(72)); // 시가
            double curHigh = Convert.ToDouble(m_FutureMstFetcher.GetHeaderValue(73)); // 고가
            double curCurVal = Convert.ToDouble(m_FutureMstFetcher.GetHeaderValue(71)); // 현재가
            double curLow = Convert.ToDouble(m_FutureMstFetcher.GetHeaderValue(74)); // 저가
            double curAsk = Convert.ToDouble(m_FutureMstFetcher.GetHeaderValue(47)); // 매도총호가수량
            double curSell = Convert.ToDouble(m_FutureMstFetcher.GetHeaderValue(53)); // 매도총호가건수
            double curBid = Convert.ToDouble(m_FutureMstFetcher.GetHeaderValue(64)); // 매수총호가수량
            double curBuy = Convert.ToDouble(m_FutureMstFetcher.GetHeaderValue(70)); // 매수총호가건수

            Console.WriteLine("fmst" + mOldTime.ToString() + "::" + mEndTime.ToString());
            if (mEndTime == mOldTime)
            {
                int endIndex = mData.Time.Length - 1;

                mData.Time[endIndex] = curTime;
                mData.Open[endIndex] = curOpen;
                mData.High[endIndex] = curHigh;
                mData.Current[endIndex] = curCurVal;
                mData.Low[endIndex] = curLow;
                mData.Ask[endIndex] = curAsk;
                mData.Sell[endIndex] = curSell;
                mData.Bid[endIndex] = curBid;
                mData.Buy[endIndex] = curBuy;
            }
            else
            {
                int cYear = 0, cMonth = 0, cDay = 0;
                GTGlobal.StockDateToSysDate(GTGlobal.mEndDate, ref cYear, ref cMonth, ref cDay);
                int cHour = 0, cMin = 0, cSec = 0;
                GTGlobal.StockTimeToSysTime(mEndTime, ref cHour, ref cMin, ref cSec);
                DateTime curDate = new DateTime(cYear, cMonth, cDay, cHour, cMin, cSec);
                // 최종적으로 받은 시간을 확인해 1분씩 작은 값들을 모두 할당해 준다.
                for (int i = GTGlobal.MaxDownloadCount - 1, j = 0; i > -1; i--, j++)
                {
                    mData.SysTime[i] = curDate.AddMinutes(-j);
                }

                // 원래의 값들을 하나씩 밀어 준다.
                GTGlobal.ShiftArrayVal(curTime, mData.Time, arrVal);
                GTGlobal.ShiftArrayVal(curOpen, mData.Open, arrVal);
                GTGlobal.ShiftArrayVal(curHigh, mData.High, arrVal);
                GTGlobal.ShiftArrayVal(curCurVal, mData.Current, arrVal);
                GTGlobal.ShiftArrayVal(curLow, mData.Low, arrVal);
                GTGlobal.ShiftArrayVal(curAsk, mData.Ask, arrVal);
                GTGlobal.ShiftArrayVal(curSell, mData.Sell, arrVal);
                GTGlobal.ShiftArrayVal(curBid, mData.Bid, arrVal);
                GTGlobal.ShiftArrayVal(curBuy, mData.Buy, arrVal);
            }
            mOldTime = mEndTime;
        }
    }
}
